package com.bdd.service.Impl;

import com.bdd.Enum.RoleEnum;
import com.bdd.entity.Role;
import com.bdd.entity.User;
import com.bdd.entity.UserRole;
import com.bdd.mapper.RoleDAO;
import com.bdd.mapper.UserDAO;
import com.bdd.mapper.UserRoleDAO;
import com.bdd.model.bo.UserBO;
import com.bdd.service.UserService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AccountException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;


@Service
public class UserServiceImpl implements UserService {

    @Autowired
    UserDAO userDao;

    @Autowired
    RoleDAO roleDAO;


    @Autowired
    UserRoleDAO userRoleDAO;

    @Override
    public UserBO login(UserBO bo) {
        String username = bo.getUsername();
        String password = bo.getPassword();
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);
        } catch (AccountException accountException) {
            throw accountException;
        } catch (IncorrectCredentialsException incorrectCredentialsException) {
            throw incorrectCredentialsException;
        }

        User user = userDao.selectByUsernameAndPassword(bo.getUsername(), bo.getPassword());
        Role role = roleDAO.selectByUserId(user.getId());
        UserBO boRes = UserBO.builder()
                .id(user.getId())
                .username(user.getUsername())
                .role(role.getRolename()).build();

        return boRes;

    }


    @Override
    public String getUserRolesByUsername(String userName) {
        return roleDAO.getUserRolesByUsername(userName);
    }

    @Override
    @Transactional
    public void add(UserBO bo) {
        User user = User.builder()
                .username(bo.getUsername())
                .password(bo.getPassword())
                .build();
        userDao.insertSelective(user);
        String roleName = bo.getRole();
        Integer roleId = RoleEnum.getIdByName(roleName);
        UserRole userRole = UserRole.builder()
                .userid(user.getId())
                .roleid(roleId)
                .build();
        userRoleDAO.insertSelective(userRole);
    }


    @Override
    @Transactional
    public void updateUserInfo(UserBO bo) {
        User user = User.builder()
                .id(bo.getId())
                .username(bo.getUsername())
                .password(bo.getPassword())
                .build();
        userDao.updateByPrimaryKeySelective(user);
        if (!ObjectUtils.isEmpty(bo.getRole())) {
            Integer roleId = RoleEnum.getIdByName(bo.getRole());
            UserRole userRole = UserRole.builder()
                    .userid(user.getId())
                    .roleid(roleId)
                    .build();
            userRoleDAO.updateByPrimaryKeySelective(userRole);
        }
    }

    @Override
    public void deleteByUserId(Integer id) {
        userDao.deleteByPrimaryKey(id);
        userRoleDAO.deleteByUserId(id);
    }

    @Override
    public Page<UserBO> list(Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum,pageSize);
        Page<UserBO> userList = userDao.selectAllUserBO();
        return userList;
    }

    @Override
    public Page<UserBO> getByNameOrId(Integer pageNum, Integer pageSize, UserBO bo) {
        PageHelper.startPage(pageNum,pageSize);
        boolean idOrNameNotNull=(!ObjectUtils.isEmpty(bo.getId()))||(!ObjectUtils.isEmpty(bo.getUsername()));
        Page<UserBO> boPage = null;
        if(idOrNameNotNull){
            boPage = userDao.selectUserByIdOrUserName(bo.getId(),bo.getUsername());
        }
        else {
            boPage = userDao.selectAllUserBO();
        }
        return boPage;
    }
}
